/* The code examples copyrighted by Nokia Corporation that are included to
 * this material are licensed to you under following MIT-style License:
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "accountsmodel.h"
#include <Accounts/Manager>

AccountsListModel::AccountsListModel(Accounts::Manager *parent)
    : QAbstractListModel(parent)
{
    QHash<int, QByteArray> roles;
    roles[AccountIdRole] = "accountid";
    roles[DisplayNameRole] = "displayname";
    roles[ProviderNameRole] = "providername";
    roles[EnabledRole] = "accountenabled";
    setRoleNames(roles);

    QObject::connect(parent, SIGNAL(accountCreated(Accounts::AccountId)),
                     this, SLOT(accountCreated(Accounts::AccountId)));
    QObject::connect(parent, SIGNAL(accountRemoved(Accounts::AccountId)),
                     this, SLOT(accountRemoved(Accounts::AccountId)));
    accounts = parent->accountList();
}

AccountsListModel::~AccountsListModel()
{
}

void AccountsListModel::accountCreated(Accounts::AccountId id)
{
    Accounts::AccountIdList new_accounts = accountManager()->accountList();

    /* find the position of the new account in the list: QAbstractItemModel
     * APIs need it */
    int accountIndex = new_accounts.indexOf(id);
    if (accountIndex < 0) {
        // Account id not present in the new list
        return;
    }

    QModelIndex parent;
    beginInsertRows(parent, accountIndex, accountIndex);
    accounts = new_accounts;
    endInsertRows();
}

void AccountsListModel::accountRemoved(Accounts::AccountId id)
{
    Accounts::AccountIdList new_accounts = accountManager()->accountList();
    /* find the position of the deleted account in the list: QAbstractItemModel
     * APIs need it */
    int accountIndex = accounts.indexOf(id);
    if (accountIndex < 0) {
        // Account id not present in the new list
        return;
    }

    QModelIndex parent;
    beginRemoveRows(parent, accountIndex, accountIndex);
    accounts = new_accounts;
    endRemoveRows();
}

// Toggle enabled state of specified account
void AccountsListModel::toggleEnabled(int accountindex)
{
    QModelIndex modelIndex = index(accountindex, 0);
    Accounts::Account *toggledAccount = account(modelIndex);
    if (toggledAccount) {
        toggledAccount->setEnabled(!toggledAccount->enabled());
        toggledAccount->sync();
        emit dataChanged(modelIndex, modelIndex);
    }
}

Accounts::Account *AccountsListModel::account(const QModelIndex &index) const
{
    return accountManager()->account(index.internalId());
}

Accounts::Manager *AccountsListModel::accountManager() const
{
    return qobject_cast<Accounts::Manager *>(QObject::parent());
}

QModelIndex AccountsListModel::index(int row, int column, const QModelIndex &parent) const
{
    if (row < 0 || column < 0 || !hasIndex(row, column, parent))
        return QModelIndex();

    return createIndex(row, column, accounts.at(row));
}

int AccountsListModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return accounts.length();
}

QVariant AccountsListModel::data(const QModelIndex &index, int role) const
{

    if (index.isValid()) {
        Accounts::AccountId accountId = index.internalId();
        Accounts::Account *account = accountManager()->account(accountId);

        switch (role) {
            case AccountIdRole:
                return QVariant(accountId);
            case DisplayNameRole:
                return QVariant(account->displayName());
            case ProviderNameRole:
                return QVariant(account->providerName());
            case EnabledRole:
                return QVariant(account->enabled());
        }
    }
    return QVariant();
}
